<script setup lang="ts">
// @ts-ignore
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
// @ts-ignore
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
// @ts-ignore
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
// @ts-ignore
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
// @ts-ignore
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
// @ts-ignore
import * as monaco from 'monaco-editor';
import { nextTick, ref, onBeforeUnmount, watch } from 'vue';
const editorRef = ref();
const props = defineProps({
  modelValue: String,
  language: String,
  readOnly: Boolean,
});
const emits = defineEmits(['update:modelValue']);
const value = ref(props.modelValue)
onBeforeUnmount(() => {
  editor.dispose();
});
// @ts-ignore
self.MonacoEnvironment = {
  getWorker(_: string, label: string) {
    if (label === 'json') {
      return new jsonWorker();
    }
    if (label === 'css' || label === 'scss' || label === 'less') {
      return new cssWorker();
    }
    if (label === 'html' || label === 'handlebars' || label === 'razor') {
      return new htmlWorker();
    }
    if (['typescript', 'javascript'].includes(label)) {
      return new tsWorker();
    }
    return new EditorWorker();
  },
};
let editor: monaco.editor.IStandaloneCodeEditor;

const editorInit = () => {
  nextTick(() => {
    monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
      noSemanticValidation: true,
      noSyntaxValidation: false,
    });
    monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
      target: monaco.languages.typescript.ScriptTarget.ES2016,
      allowNonTsExtensions: true,
    });

    !editor
      ? (editor = monaco.editor.create(editorRef.value, {
        value: JSON.parse(JSON.stringify(props.modelValue)), // 编辑器初始显示文字
        language: props.language, // 语言支持自行查阅demo
        automaticLayout: true, // 自适应布局
        theme: 'vs-dark', // 官方自带三种主题vs, hc-black, or vs-dark
        foldingStrategy: 'indentation',
        renderLineHighlight: 'all', // 行亮
        selectOnLineNumbers: true, // 显示行号
        minimap: {
          enabled: false,
        },
        readOnly: !props.readOnly, // 只读
        fontSize: 14, // 字体大小
        scrollBeyondLastLine: false, // 取消代码后面一大段空白
        overviewRulerBorder: false, // 不要滚动条的边框
      }))
      : editor.setValue(props.modelValue);
    // console.log(editor)
    // 监听值的变化
    editor.onDidChangeModelContent((val: any) => {
      const valStr = editor.getValue();
      value.value = valStr
      emits('update:modelValue', valStr);
    });
  });
};
editorInit();
// 是否禁用
watch(() => props.readOnly, () => {
  editor && editor.updateOptions({
    readOnly: props.readOnly
  })
})
// 是否设置参数
watch(() => props.modelValue, () => {
  // 内置变量判断是否有变化，进而判断是否事变量change
  if (props.modelValue !== value.value) {
    value.value = props.modelValue
    editor && editor.setValue(props.modelValue)
  }
})
</script>

<template>
  <div ref="editorRef" class="editor"></div>
</template>
<style lang="scss" scoped>
.editor {
  height: 100%;
  min-height: 300px;
}
</style>